package com.common;



import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;
import java.util.*;

public class UtilTools {
	/**
	 * Md5密码加密
	 * @param str
	 * @return
	 */
	public static String Md5(String str) {
		MessageDigest messageDigest = null;

		try {
			messageDigest = MessageDigest.getInstance("MD5");
			messageDigest.reset();
			messageDigest.update(str.getBytes("UTF-8"));
		} catch (NoSuchAlgorithmException e) {
			System.out.println("NoSuchAlgorithmException caught!");
			System.exit(-1);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		byte[] byteArray = messageDigest.digest();
		StringBuffer md5StrBuff = new StringBuffer();
		for (int i = 0; i < byteArray.length; i++) {
			if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
				md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));
			else
				md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
		}
		return md5StrBuff.toString();
	}
	/**
	 * 获取访问用户IP地址
	 * @param request
	 * @return
	 */
	public static String getClientIp(HttpServletRequest request){
		String ip = request.getHeader("x-forwarded-for");
		if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		if(ip!=null && ip.indexOf(",")!=-1)ip=ip.split(",")[0];//分割代理地址
		return ip;
	}


	/**
	 * 复制文件
	 * @param sourceFile	源文件
	 * @param targetFile	目标文件
	 * @throws IOException
	 */
	public static void copyFile(File sourceFile, File targetFile) throws IOException {
		BufferedInputStream inBuff = null;
		BufferedOutputStream outBuff = null;
		try {
			// 新建文件输入流并对它进行缓冲
			inBuff = new BufferedInputStream(new FileInputStream(sourceFile));

			if(!targetFile.exists()){
				targetFile.mkdirs();
				targetFile.delete();
				targetFile.createNewFile();
			}
			// 新建文件输出流并对它进行缓冲
			outBuff = new BufferedOutputStream(new FileOutputStream(targetFile));

			// 缓冲数组
			byte[] b = new byte[1024 * 5];
			int len;
			while ((len = inBuff.read(b)) != -1) {
				outBuff.write(b, 0, len);
			}
			// 刷新此缓冲的输出流
			outBuff.flush();
		} finally {
			// 关闭流
			if (inBuff != null)
				inBuff.close();
			if (outBuff != null)
				outBuff.close();
		}
	}
	/**
	 * 随机字符串
	 * @param length
	 * @return
	 */
	public static String RandomString(int length) {
		StringBuffer buffer = new StringBuffer("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
		StringBuffer sb = new StringBuffer();
		Random r = new Random();
		int range = buffer.length();
		for (int i = 0; i < length; i ++) {
			sb.append(buffer.charAt(r.nextInt(range)));
		}
		return sb.toString();
	}

	/**
	 * 数字转换为2位小数的Double类型
	 * @param number
	 * @return
	 */
	public static Double getRoundHalfUp(Object number){
		return new BigDecimal((Double)number).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	public static String randomNumber(int length) {
		StringBuffer buffer = new StringBuffer("0123456789");
		StringBuffer sb = new StringBuffer();
		Random r = new Random();
		int range = buffer.length();
		for (int i = 0; i < length; i ++) {
			sb.append(buffer.charAt(r.nextInt(range)));
		}
		return sb.toString();
	}
	/**
	 * 读文本文件,仅限文本。
	 * @param filePath 文件路径
	 * @return
	 */
	public static String readTXTFile(String filePath,String encode){
		File file=new File(filePath);
		StringBuffer sb=new StringBuffer();
		try {
			BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream(file), encode));
			String line=null;
			while((line=br.readLine())!=null){
				sb.append(line);
				sb.append("\n");
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return sb.toString();
	}
	/**
	 * 替换字符串
	 * @param sourceStr		源字符串
	 * @param regularMap	<被替换的字符串,替换成的字符串>
	 * @return
	 */
	public static String replaceStr(String sourceStr,Map<String, String> regularMap){
		Iterator<String> keys=regularMap.keySet().iterator();
		while(keys.hasNext()){
			String key = keys.next();
			sourceStr=UtilTools.replaceStr(sourceStr, key, regularMap.get(key));
		}
		return sourceStr;
	}
	/**
	 * 替换字符串
	 * @param sourceStr	源字符串
	 * @param from		要替换的目标字符串
	 * @param to		要替换的字符串
	 * @return
	 */
	public static String replaceStr(String sourceStr,String from,String to){
		StringBuffer buf =new StringBuffer(sourceStr);
		int i = 0;
		if ((i = sourceStr.indexOf(from, i)) >= 0) {
			char[] cSrc = sourceStr.toCharArray();
			char[] cTo = to.toCharArray();
			int len = from.length();
			buf = new StringBuffer(cSrc.length);
			buf.append(cSrc, 0, i).append(cTo);
			i += len;
			int j = i;
			while ((i = sourceStr.indexOf(from, i)) > 0) {
				buf.append(cSrc, j, i - j).append(cTo);
				i += len;
				j = i;
			}
			buf.append(cSrc, j, cSrc.length - j);
		}
		return buf.toString();
	}
	/**
	 * 写文本文件,仅限文本。
	 * @param path 文本路径
	 * @param context	内容
	 * @throws IOException
	 */
	public static void writeTXTFile(String path,String context,String encode) throws IOException{
		File f = new File(path);
		if(!f.exists()){
			f.mkdirs();
			f.delete();
			f.createNewFile();
		}else{
			f.delete();
			f.createNewFile();
		}
		BufferedWriter output = new BufferedWriter(new OutputStreamWriter( new FileOutputStream(f), encode));
		output.write(context);
		output.flush();
		output.close();
	}


	public static boolean isNullOrBlank(String str) {
		return (str == null || "".equals(str.trim()));
	}

	public static boolean isNullOrBlank(Long str) {
		return str == null;
	}



	public static String formatDouble(String doubleStr, String format) {
		DecimalFormat decimalFormat = new DecimalFormat(format);
		if (UtilTools.isNullOrBlank(doubleStr)) {
			return "";
		}
		try {
			return decimalFormat.format(Double.parseDouble(doubleStr.trim()));
		} catch (Exception e) {
			return doubleStr;
		}
	}

	public static String formatDouble(Double src,String format){
		DecimalFormat decimalFormat = new DecimalFormat(format);
		if(null == src ){
			return null;
		}
		return decimalFormat.format(src);
	}
	/**
	 * 删除文件或文件夹
	 * @param file
	 */
	public static void deleteFile(File file) {
		if (file.exists()) {
			if (file.isFile()) {
				file.delete();
			} else if (file.isDirectory()) {
				File files[] = file.listFiles();
				for (int i = 0; i < files.length; i++) {
					deleteFile(files[i]);
				}
			}
			file.delete();
		} else {
			System.out.println("所删除的文件不存在！" + '\n');
		}
	}


	/**
	 * 格式化数值:采用向上进1处理非0小数
	 *
	 * @param val Double
	 * @return
	 */
	public static Double roundup(Double val) {
		return new BigDecimal(val).setScale(0, BigDecimal.ROUND_UP).doubleValue();
	}

	/**
	 * 原页参数回传
	 * @param request
	 */
	public static void callBackRequest(HttpServletRequest request){
		Iterator<String> it = request.getParameterMap().keySet().iterator();
		while(it.hasNext()){
			String rkey =  it.next();
			request.setAttribute(rkey, request.getParameter(rkey));
		}
	}

	/**
	 * 加百分号
	 * @param str
	 * @param addflag 0：前后都加,1:前面加,2:后面加
	 */
	public static String addPerSign(String str,int addflag){
		String result=str;
		if(!UtilTools.isNullOrBlank(str)){
			StringBuilder sb=new StringBuilder(str);
			result=addflag==0?sb.insert(0, '%').append('%').toString():addflag==1?sb.insert(0, '%').toString():addflag==2?sb.append('%').toString():sb.toString();
		}
		return result;
	}


	/**
	 * 从request中取出表单设置属性字符串
	 * @param request
	 * @return
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 */
	public static String getFormParm(HttpServletRequest request) throws Exception{
		StringBuilder sb = new StringBuilder();
		String result = "";
		for (Enumeration enumeration =request.getParameterNames();
			 enumeration.hasMoreElements();) {
			Object obj = enumeration.nextElement();
			String name = obj.toString();
			sb.append(","+name);
//		          String s =new String(request.getParameterValues((String) obj)[0].getBytes("ISO-8859-1"),"utf-8");
//		          System.out.println("Parameter name =" + obj.toString() + ", Parameter value =" + s);
		}
		if(sb.length()>0){
			result = sb.substring(1);
		}
		return result;
	}



	/**
	 * 将list<String> 转成 逗号分隔的string
	 * @param strList
	 * @return
	 */
	public static String listToStr(List<String> strList){
		if(strList.size()<1){
			return "";
		}
		StringBuffer sb = new StringBuffer();
		for (String str : strList) {
			sb.append(str+", ");
		}
		String str = sb.toString();
		return str.substring(0, str.length()-1);
	}


	/**
	 * 将Double数值四舍五入到指定小数位
	 *
	 * @param val
	 * @param scale
	 * @return
	 */
	public static Double setScale(Double val, int scale) {
		return new BigDecimal(val).setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	public static Double setScale(Double val) {
		return setScale(val, 4);
	}


	/**
	 * 获取request
	 * @return
	 */
	public static HttpServletRequest getRequest(){
		ServletRequestAttributes sa=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
		HttpServletRequest request = null;
		if(sa!=null) {
			request = sa.getRequest();
		}
		return request;
	}

//	/**
//	 * 取shiroCookie值
//	 * @return
//	 */
//	public static String[] getShiroCookies(){
//		HttpServletRequest request=getRequest();
//		String[] rs=new String[2];
//		if(request!=null){
//			Cookie[] cookies = request.getCookies();
//			Arrays.asList(cookies).stream().filter(c -> c.getName().equals(Constant.ShiroSession_NAME)).forEach(c -> {rs[0]=c.getName();rs[1]=c.getValue();});
//		}
//		return rs;
//	}

	/**
	 * 序列化对象
	 * @param object
	 * @return
	 */
	public static byte[] serialize(Object object) {
		ObjectOutputStream oos = null;
		ByteArrayOutputStream baos = null;
		try {
			baos = new ByteArrayOutputStream();
			oos = new ObjectOutputStream(baos);
			oos.writeObject(object);
			byte[] bytes = baos.toByteArray();
			return bytes;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * 反序列化对象
	 * @param bytes
	 * @return
	 */
	public static Object deserialize(byte[] bytes) {
		ByteArrayInputStream bais = null;
		try {
			bais = new ByteArrayInputStream(bytes);
			ObjectInputStream ois = new ObjectInputStream(bais);
			return ois.readObject();
		} catch (Exception e) {

		}
		return null;
	}

	/**
	 * 带x的表达式代入计算
	 *
	 * @param expression g(x)=(x+1000)*0.8-100+50 这种形式的表达式
	 * @param xVal       待代入表达式中的x值
	 * @return
	 */
//    public static Double caculateExpression(String expression, Double xVal) {
//        try {
//            Expression exp = ExpressionFactory.createExpression(expression);
//            Parameters parameters = ExpressionFactory.createParameters();
//            parameters.addParameter("x", NumberFactory.createReal(xVal));
//            Double result = exp.evaluate(parameters).getRealValue();
//            //logger.info("表达式计算结果,expression:" + expression + ";x=" + xVal + ";result=" + result);
//            return result;
//        } catch (Exception e) {
//            logger.info("表达式计算失败,expression:" + expression + ";x=" + xVal, e);
//        }
//        return 0d;
//    }

	/**
	 * 拿UUID
	 * @return
	 */
	public static String getUUID() {
		return UUID.randomUUID().toString().toUpperCase();
	}

	/**
	 * 检查List集合里面是否包含重复值
	 * str为数据基本类型
	 * @param str
	 * @return
	 */
	public static boolean checkRepeat(List<Object> str){
		Integer size = str.size();
		Integer sum = 0;
		Object []obj = str.toArray();
		Object temp = obj[0];
		for(int i=0;i<str.size();i++){
			if(obj[i].equals(temp)){
				sum++;
			}
		}
		return sum==size;
	}


	/**
	 * 发送POST请求
	 * @param url
	 * @param postParameters
	 * @param glzz
	 * @param restTemplate
	 * @param <T>
	 * @return
	 */
	public static <T> T POST(String url, MultiValueMap postParameters, Class<T> glzz, RestTemplate restTemplate){
		HttpEntity<MultiValueMap> request  = new HttpEntity<MultiValueMap>(postParameters,new HttpHeaders());
		T contractInfo=restTemplate.postForObject(url,request,glzz);
		return contractInfo;
	}

	public static ReqObject _POST(String url,HttpServletRequest request){
		return new ReqObject(url,request);
	}

	public static ReqObject _POST(String url){
		return new ReqObject(url);
	}

	/**
	 * 调用工作流发起流程API
	 * @param flowId 要发起流程的ID
	 * @param dataId 工作流业务ID
	 * @param title 流程标题
	 * @return ResponseData 返回供前端使用的业务数据对象实例
	 * @exception
	 */
	public static Map<String,Object> startWorkflow (String flowId, String formid,String tablename,String dataId, String title,String username,String Url) throws Exception {
		org.springframework.util.MultiValueMap<String, String> postParameters = new LinkedMultiValueMap<String, String>();
		postParameters.add("username",username);
		//String sessionID=UtilTools.POST("http://10.1.10.143:8091/hz7/SaleSystemSSO",postParameters,String.class,new RestTemplate());
		String sessionID=UtilTools.POST(Url+"/hz7/SaleSystemSSO",postParameters,String.class,new RestTemplate());
		if(!UtilTools.isNullOrBlank(sessionID)) {
			postParameters.clear();
			postParameters.add("flowid", flowId);
			postParameters.add("formid", formid);
			postParameters.add("tablename", tablename);
			postParameters.add("dataid", dataId);
			postParameters.add("title", title);
			HttpHeaders head=new HttpHeaders();
			head.add("Cookie","JSESSIONID="+sessionID.trim());
			HttpEntity<MultiValueMap> request  = new HttpEntity<MultiValueMap>(postParameters,head);
			//return new RestTemplate().postForObject("http://10.1.10.143:8091/hz7/system/startWorkflow.wf",request,Map.class);
			return new RestTemplate().postForObject(Url+"/hz7/system/startWorkflow.wf",request,Map.class);
		}
		return null;
	}

	/**
	 * 获取当前请求链唯一标识
	 * @return
	 */
	public static String currTrackId(){
		try {
			Class span=Class.forName("org.springframework.cloud.sleuth.Span");
			return getRequest().getHeader((String)span.getDeclaredField("TRACE_ID_NAME").get(null));
		} catch (Exception e) {
			return null;
		}

	}

	/**
	 * 根据浏览器设置下载文件名编码
	 * @param request
	 * @param response
	 * @param filename
	 * @throws Exception
	 */
	public static void setDownloadFileName(HttpServletRequest request, HttpServletResponse response, String filename) throws Exception {
		//判断浏览器是否是Safari,如果是则用另外的编码方式编码文件名,防止下载中文乱码
		//2018-04-09 我靠...chrome居然有Safari关键字...
		String ua=request.getHeader("User-Agent");
		Boolean isSafari=(ua.indexOf("Safari")!=-1 && ua.indexOf("Chrome")==-1?true:false);
		if(isSafari)response.setHeader("Content-disposition", "attachment;filename="+ new String(filename.getBytes("UTF-8"),"ISO-8859-1"));
		else response.setHeader("Content-disposition", "attachment;filename="+ java.net.URLEncoder.encode(filename, "UTF-8"));
	}

}
